package app.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import app.entity.CtrlBean;
import app.entity.IOTPBean;
import app.entity.IOTPBody;
import app.htby.utils.Code;
import app.htby.utils.IOTSUtils;
import app.htby.utils.IotpBodyUtils;
import app.htby.utils.SocketUtils;
import app.socket.client.CtrlConnClientRunnable;

/**
 * 控制端 对外的接口，此类为 控制接口 文档为 02_IOTP协议描述.doc - 2.2控制协议
 * 
 * @author lfy.xys
 * @date 2018年5月21日
 *
 */
@RestController
@RequestMapping("webctrl/webcontroller")
public class WebController {

	private static Logger logger = LoggerFactory.getLogger(WebController.class);

	/** iotserver 的ip */
	@Value("${sysconfig.iotServer.ip}")
	private String ip;
	/** iotserver 的port */
	@Value("${sysconfig.iotServer.port}")
	private String port;

	/**
	 * 接收使用 https方式，发送给iots使用 协议体方式
	 * 
	 * 接收协议 http://域名/IOServer标识/分组标识/设备标识/变量标识/写变量值_时间戳_超时时间_尝试次数
	 * http://htby.com/1/2/3/4/5_2018-05-21 09:00:00_300000_5
	 */
	@RequestMapping("/ctrlManage")
	public String ctrlManage(@RequestParam Map<String, Object> params) {
		Date startDate = new Date();// 调用时间
		Date endDate = new Date(startDate.getTime() + SocketUtils.TIME_OUT);// 结束时间
		logger.info("endDate : {}",endDate);
		
		String resultMsg = "";// 返回结果
		String runnableId = IOTSUtils.getUUID();// 生成唯一id
		IOTSUtils.ctrlResultMap.put(runnableId, SocketUtils.WAITING_CODE);

		String agreement = (String) params.get("agreement");// 获取接口 的 协议agreement

		String[] str = agreement.substring(agreement.lastIndexOf("/")).split("_");
		SocketUtils.TIME_OUT = Integer.parseInt(str[2]);// 获取超时时间
		
		// 将 协议内容 包装成 协议体
		List<byte[]> byteList = getIOTPBean(agreement, runnableId);
		try {
			for (byte[] bs : byteList) {
				// 循环发送 socket发送
				CtrlConnClientRunnable r = new CtrlConnClientRunnable(runnableId, ip, Integer.parseInt(port), bs);
				new Thread(r).start();
			}
		} catch (Exception e) {
			resultMsg = SocketUtils.ERROR_CODE;// 返回错误码
		}

		// 异步发送socket，但是同步等待结果.
		logger.info("runnableId1:" + runnableId);
		while (true) {
			Object result = IOTSUtils.ctrlResultMap.get(runnableId);
			// 如果结果没有变化，则继续 查询等待。
			if (!SocketUtils.WAITING_CODE.equals(result)) {
				byte[] bytes = (byte[]) IOTSUtils.ctrlResultMap.get(runnableId);
				// 结果不是等待，则得到返回值，结束循环
//				logger.info("result:" + Arrays.toString(bytes));
				// 将结果 转换
				IotpBodyUtils ibu = new IotpBodyUtils();
				Code c = ibu.toIotpBean(bytes);
				logger.info("code:" + c.toString());
				IOTPBean iotpBean = ibu.getIotpBean();
				IOTPBody body = iotpBean.getBody();
				logger.info("body:" + body.toString());
				//获得协议体
				List<String> list = body.getBodyList();
				resultMsg = list.toString();
				// TODO 将协议信息保存入log
				
				break;
			} else if (SocketUtils.ERROR_CODE.equals(resultMsg)) {
				// 报错，结束循环
				break;
			} else if (new Date().after(endDate)) {
				// a.after(b) 返回一个boolean，如果a的时间在b之后（不包括等于）返回true
				// a.before(b) 返回一个boolean，如果a的时间在b之前（不包括等于）返回true
				logger.info("new Date : {}",new Date());
				
				
				// 超时，结束循环
				resultMsg = SocketUtils.TIMEOUT_CODE;
				break;
			}

			try {
				// 每 ctyle 秒遍历一次
				logger.info("{}秒后继续遍历...", SocketUtils.ctyle);
				Thread.sleep(SocketUtils.ctyle);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		logger.info("resultMsg:" + resultMsg);
		return resultMsg;// 状态信息
	}

	/**
	 * 生成 IOTPBean
	 * 
	 * @author lfy.xys
	 * @date 2018年5月24日
	 *
	 * @param msg
	 * @param runnableId
	 * @return
	 */
	public static List<byte[]> getIOTPBean(String agreement, String runnableId) {
		IOTPBean bean = new IOTPBean();
		bean.setTag(0x1011);// 写死
		bean.setType(3);// 控制消息
		bean.setSource_id(10001);//
		bean.setSource_type(IOTSUtils.THIS_SYSTEM_ID);// 设置系统 - 源类型号
		bean.setSequence_id(111);// 拼接包使用的id
		// bean.setSequence_sub_id(0);// 不手动
		// bean.setLicense("");

		IOTPBody body = new IOTPBody();
		body.setSubtype(1);// 是什么消息体

		// 设置协议体
		CtrlBean cb = new CtrlBean();
		cb.setSendMsg(agreement);
		cb.setId(runnableId);

		List<String> bodyList = new ArrayList<String>();
		bodyList.add(JSONObject.toJSONString(cb));
		body.setBodyList(bodyList);

		bean.setBody(body);
		bean.setEnd(0x1213);

		IotpBodyUtils ibu = new IotpBodyUtils();

		return ibu.toByteArray(bean);
	}

	/**
	 * 测试
	 * 
	 * @author lfy.xys
	 * @date 2018年5月23日
	 *
	 * @param params
	 * @return
	 */
	@RequestMapping("/ctrlManageTest")
	public String ctrlManageTest(@RequestParam Map<String, Object> params) {

		String agreement = "http://htby.com/1/2/3/4/5_2018-05-21 09:00:00_300000_5";
		String ip = "localhost";
		int port = 8888;

		params.put("agreement", agreement);
		params.put("ip", ip);
		params.put("port", port);

		return this.ctrlManage(params);// 状态码
	}

	
	
}
